package com.kennedy.springboot.component;

import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.QueueViewMBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.OpenDataException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by tao.zeng on 2017/8/1.
 */
@Component
public class ActiveMQUtil {

    private static final String connectorPort = "1093";
    private static final String connectorPath = "/jmxrmi";
    private static final String jmxDomain = "org.apache.activemq";
    private static JmsTemplate jmsTemplate;

    @Autowired
    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }


    public static Long getQueueSize(String queueName) {
        Map<String, Long> queueMap = getAllQueueSize();
        Long queueSize = 0L;
        if (queueMap.size() > 0) {
            queueSize = queueMap.get(queueName);
        }
        return queueSize;
    }


    public static Map<String, Long> getAllQueueSize() {
        Map<String, Long> queueMap = new HashMap<String, Long>();
        BrokerViewMBean mBean = null;
        MBeanServerConnection connection = null;
        try {
            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + connectorPort + connectorPath);
            JMXConnector connector = JMXConnectorFactory.connect(url);
            connector.connect();
            connection = connector.getMBeanServerConnection();
            ObjectName name = new ObjectName(jmxDomain + ":brokerName=localhost,type=Broker");
            mBean = MBeanServerInvocationHandler.newProxyInstance(connection, name, BrokerViewMBean.class, true);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MalformedObjectNameException e) {
            e.printStackTrace();
        }
        if (mBean != null) {
            for (ObjectName queueName : mBean.getQueues()) {
                QueueViewMBean queueMBean = MBeanServerInvocationHandler.newProxyInstance(connection, queueName, QueueViewMBean.class, true);
                queueMap.put(queueMBean.getName(), queueMBean.getQueueSize());
                try {
                    CompositeData compositeData = queueMBean.getMessage(queueMBean.getName());
                } catch (OpenDataException e) {
                    e.printStackTrace();
                }
            }
        }
        return queueMap;
    }

    public static void remove(String s) {
        BrokerViewMBean mBean = null;
        try {
            mBean = getMBean(mBean);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MalformedObjectNameException e) {
            e.printStackTrace();
        }
        if (null != mBean) {
            try {
                mBean.removeQueue(s);
            } catch (Exception e) {
            }
        }

    }

    private static BrokerViewMBean getMBean(BrokerViewMBean mBean) throws IOException, MalformedObjectNameException {
        MBeanServerConnection connection = null;
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + connectorPort + connectorPath);
        JMXConnector connector = JMXConnectorFactory.connect(url);
        connector.connect();
        connection = connector.getMBeanServerConnection();
        ObjectName name = new ObjectName(jmxDomain + ":brokerName=localhost,type=Broker");
        mBean = MBeanServerInvocationHandler.newProxyInstance(connection, name, BrokerViewMBean.class, true);
        return mBean;
    }


    public static void sendMsg(String msg) {
        jmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
    }
}
